/**
 * \file
 * \brief ATCA Hardware abstraction layer for PIC32MX695F512H I2C over plib drivers.
 *
 * This code is structured in two parts.  Part 1 is the connection of the ATCA HAL API to the physical I2C
 * implementation. Part 2 is the xxx I2C primitives to set up the interface.
 *
 * Prerequisite:
 *
 * \copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
 *
 * \page License
 *
 * Subject to your compliance with these terms, you may use Microchip software
 * and any derivatives exclusively with Microchip products. It is your
 * responsibility to comply with third party license terms applicable to your
 * use of third party software (including open source software) that may
 * accompany Microchip software.
 *
 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
 * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
 * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
 * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT,
 * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE
 * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF
 * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE
 * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL
 * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED
 * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR
 * THIS SOFTWARE.
 */

#include <stdio.h>
#include <string.h>

#include "hal/atca_hal.h"
#include "hal/hal_xilinx_iic.h"

/******************************************************************************
 *
 * Copyright (C) 2006 - 2014 Xilinx, Inc.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Except as contained in this notice, the name of the Xilinx shall not be used
 * in advertising or otherwise to promote the sale, use or other dealings in
 * this Software without prior written authorization from Xilinx.
 *
 ******************************************************************************/
/*****************************************************************************/
/**
 * @file xiic_repeated_start_example.c
 *
 * This file consists of a interrupt mode design example to demonstrate the use
 * of repeated start using the XIic driver.
 *
 * The XIic_MasterSend() API is used to transmit the data and XIic_MasterRecv()
 * API is used to receive the data.
 *
 * The IIC devices that are present on the Xilinx boards donot support the
 * repeated start option. These examples have been tested with an IIC
 * device external to the boards.
 *
 * This code assumes that no Operating System is being used.
 *
 * @note
 *
 * None.
 *
 * <pre>
 * MODIFICATION HISTORY:
 *
 * Ver   Who  Date	 Changes
 * ----- ---- -------- -----------------------------------------------
 * 1.00a mta  02/20/06 Created.
 * 2.00a sdm  09/22/09 Updated to use the HAL APIs, replaced call to
 *		      XIic_Initialize API with XIic_LookupConfig and
 *		      XIic_CfgInitialize. Updated the example with a
 *	              fix for CR539763 where XIic_Start was being called
 *	              instead of XIic_Stop. Added code for setting up the
 *	              StatusHandler callback.
 * 3.4   ms   01/23/17 Added xil_printf statement in main function to
 *                     ensure that "Successfully ran" and "Failed" strings
 *                     are available in all examples. This is a fix for
 *                     CR-965028.
 *
 * </pre>
 *
 ******************************************************************************/

/***************************** Include Files *********************************/

#include "xparameters.h"
#include "xiic.h"
//#include "xintc.h"
//#include "xil_exception.h"
#include "xil_printf.h"

#define IIC_BASE_ADDRESS	XPAR_IIC_0_BASEADDR

/************************** Constant Definitions *****************************/

/*
 * The following constants map to the XPAR parameters created in the
 * xparameters.h file. They are defined here such that a user can easily
 * change all the needed parameters in one place.
 */
#define IIC_DEVICE_ID		XPAR_IIC_0_DEVICE_ID
/*#define INTC_DEVICE_ID		XPAR_INTC_0_DEVICE_ID
 #define IIC_INTR_ID		XPAR_INTC_0_IIC_0_VEC_ID*/

static ATCAI2CMaster_t i2c_hal_data[MAX_I2C_BUSES];   // map logical, 0-based bus number to index

ATCAIfaceCfg discoverCfg = { .iface_type = ATCA_I2C_IFACE, .devtype = ATECC608A, .atcai2c.slave_address = 0xc0,
		.atcai2c.bus = 0, .atcai2c.baud = 100000,
		//.atcai2c.baud = 100000,
		.wake_delay = 800, .rx_retries = 3 };

/*
 * The following constant defines the address of the IIC
 * device on the IIC bus. Note that since the address is only 7 bits, this
 * constant is the address divided by 2.
 */
#define SLAVE_ADDRESS	0xc0	/* 0xE0 as an 8 bit number. */

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Function Prototypes ******************************/

int IicRepeatedStartExample();

static void SendHandler(XIic *InstancePtr);
static void ReceiveHandler(XIic *InstancePtr);
static void StatusHandler(XIic *InstancePtr, int Event);

/************************** Variable Definitions *****************************/

//XIic IicInstance;
//XIntc InterruptController;


uint32_t loopctr;

unsigned RecvDataVar(UINTPTR BaseAddress, u8 *BufferPtr,
			 u8 Option, int maxsize);

unsigned XIic_RecvVar(UINTPTR BaseAddress, u8 Address,
			u8 *BufferPtr, u8 Option, int maxsize)
{
	u32 CntlReg;
	unsigned RemainingByteCount;
	volatile u32 StatusReg;

	/* Tx error is enabled incase the address (7 or 10) has no device to
	 * answer with Ack. When only one byte of data, must set NO ACK before
	 * address goes out therefore Tx error must not be enabled as it will go
	 * off immediately and the Rx full interrupt will be checked.  If full,
	 * then the one byte was received and the Tx error will be disabled
	 * without sending an error callback msg
	 */
	XIic_ClearIisr(BaseAddress,
			XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK |
			XIIC_INTR_ARB_LOST_MASK);

	/* Set receive FIFO occupancy depth for 1 byte (zero based) */
	XIic_WriteReg(BaseAddress,  XIIC_RFD_REG_OFFSET, 0);


	/* Check to see if already Master on the Bus.
	 * If Repeated Start bit is not set send Start bit by setting MSMS bit
	 * else Send the address
	 */
	CntlReg = XIic_ReadReg(BaseAddress,  XIIC_CR_REG_OFFSET);
	if ((CntlReg & XIIC_CR_REPEATED_START_MASK) == 0) {
		/* 7 bit slave address, send the address for a read operation
		 * and set the state to indicate the address has been sent
		 */
		XIic_Send7BitAddress(BaseAddress, Address,
					XIIC_READ_OPERATION);


		/* MSMS gets set after putting data in FIFO. Start the master
		 * receive operation by setting CR Bits MSMS to Master, if the
		 * buffer is only one byte, then it should not be acknowledged
		 * to indicate the end of data
		 */
		CntlReg = XIIC_CR_MSMS_MASK | XIIC_CR_ENABLE_DEVICE_MASK;
/*		if (ByteCount == 1) {
			CntlReg |= XIIC_CR_NO_ACK_MASK;
		}
*/
		/* Write out the control register to start receiving data and
		 * call the function to receive each byte into the buffer
		 */
		XIic_WriteReg(BaseAddress,  XIIC_CR_REG_OFFSET, CntlReg);

		/* Clear the latched interrupt status for the bus not busy bit
		 * which must be done while the bus is busy
		 */
		StatusReg = XIic_ReadReg(BaseAddress,  XIIC_SR_REG_OFFSET);

		while ((StatusReg & XIIC_SR_BUS_BUSY_MASK) == 0) {
			StatusReg = XIic_ReadReg(BaseAddress,
						  XIIC_SR_REG_OFFSET);
		}

		XIic_ClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);
	} else {
	        /* Before writing 7bit slave address the Direction of Tx bit
		 * must be disabled
		 */
		CntlReg &= ~XIIC_CR_DIR_IS_TX_MASK;
/*		if (ByteCount == 1) {
			CntlReg |= XIIC_CR_NO_ACK_MASK;
		}
*/
		XIic_WriteReg(BaseAddress,  XIIC_CR_REG_OFFSET, CntlReg);
		/* Already owns the Bus indicating that its a Repeated Start
		 * call. 7 bit slave address, send the address for a read
		 * operation and set the state to indicate the address has been
		 * sent
		 */
		XIic_Send7BitAddress(BaseAddress, Address,
					XIIC_READ_OPERATION);
	}
	/* Try to receive the data from the IIC bus */

	RemainingByteCount = RecvDataVar(BaseAddress, BufferPtr,
				      Option, maxsize);

	CntlReg = XIic_ReadReg(BaseAddress,  XIIC_CR_REG_OFFSET);
	if ((CntlReg & XIIC_CR_REPEATED_START_MASK) == 0) {
		/* The receive is complete, disable the IIC device if the Option
		 * is to release the Bus after Reception of data and return the
		 * number of bytes that was received
		 */
		XIic_WriteReg(BaseAddress,  XIIC_CR_REG_OFFSET, 0);
	}

	/* Wait until I2C bus is freed, exit if timed out. */
/*	if (XIic_WaitBusFree(BaseAddress) != XST_SUCCESS) {
		return 0;
	}
*/
	/* Return the number of bytes that was received */
	return RemainingByteCount;
}

unsigned RecvDataVar(UINTPTR BaseAddress, u8 *BufferPtr,
			 u8 Option, int maxsize)
{
	u32 CntlReg;
	u32 IntrStatusMask;
	u32 IntrStatus;
	int ByteCount = 64;	// dummy gets changed
	int first = 1;
	/* Attempt to receive the specified number of bytes on the IIC bus */

	while (ByteCount > 0) {
		/* Setup the mask to use for checking errors because when
		 * receiving one byte OR the last byte of a multibyte message an
		 * error naturally occurs when the no ack is done to tell the
		 * slave the last byte
		 */
		if (ByteCount == 1) {
			IntrStatusMask =
				XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK;
		} else {
			IntrStatusMask =
				XIIC_INTR_ARB_LOST_MASK |
				XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_BNB_MASK;
		}

		/* Wait for the previous transmit and the 1st receive to
		 * complete by checking the interrupt status register of the
		 * IPIF
		 */
		while (1) {
			IntrStatus = XIic_ReadIisr(BaseAddress);
			if (IntrStatus & XIIC_INTR_RX_FULL_MASK) {
				break;
			}
			/* Check the transmit error after the receive full
			 * because when sending only one byte transmit error
			 * will occur because of the no ack to indicate the end
			 * of the data
			 */
			if (IntrStatus & IntrStatusMask) {
				return ByteCount;
			}
		}

		CntlReg = XIic_ReadReg(BaseAddress,  XIIC_CR_REG_OFFSET);

		/* Special conditions exist for the last two bytes so check for
		 * them. Note that the control register must be setup for these
		 * conditions before the data byte which was already received is
		 * read from the receive FIFO (while the bus is throttled
		 */
		if (ByteCount == 1) {
			if (Option == XIIC_STOP) {

				/* If the Option is to release the bus after the
				 * last data byte, it has already been read and
				 * no ack has been done, so clear MSMS while
				 * leaving the device enabled so it can get off
				 * the IIC bus appropriately with a stop
				 */
				XIic_WriteReg(BaseAddress,  XIIC_CR_REG_OFFSET,
					 XIIC_CR_ENABLE_DEVICE_MASK);
			}
		}

		/* Before the last byte is received, set NOACK to tell the slave
		 * IIC device that it is the end, this must be done before
		 * reading the byte from the FIFO
		 */
		if (ByteCount == 2) {
			/* Write control reg with NO ACK allowing last byte to
			 * have the No ack set to indicate to slave last byte
			 * read
			 */
			XIic_WriteReg(BaseAddress,  XIIC_CR_REG_OFFSET,
				 CntlReg | XIIC_CR_NO_ACK_MASK);
		}

		/* Read in data from the FIFO and unthrottle the bus such that
		 * the next byte is read from the IIC bus
		 */
		*BufferPtr++ = (u8) XIic_ReadReg(BaseAddress,
						  XIIC_DRR_REG_OFFSET);
		if (first) {
			if (BufferPtr[0] < ATCA_RSP_SIZE_MIN) {
				return 0;
			}
			if (BufferPtr[0] > maxsize) {
				return 0;
			}
			ByteCount = BufferPtr[0]-1;
			first = 0;
		}

		if ((ByteCount == 1) && (Option == XIIC_REPEATED_START)) {

			/* RSTA bit should be set only when the FIFO is
			 * completely Empty.
			 */
			XIic_WriteReg(BaseAddress,  XIIC_CR_REG_OFFSET,
				 XIIC_CR_ENABLE_DEVICE_MASK | XIIC_CR_MSMS_MASK
				 | XIIC_CR_REPEATED_START_MASK);

		}

		/* Clear the latched interrupt status so that it will be updated
		 * with the new state when it changes, this must be done after
		 * the receive register is read
		 */
		XIic_ClearIisr(BaseAddress, XIIC_INTR_RX_FULL_MASK |
				XIIC_INTR_TX_ERROR_MASK |
				XIIC_INTR_ARB_LOST_MASK);
		ByteCount--;
	}

	if (Option == XIIC_STOP) {

		/* If the Option is to release the bus after Reception of data,
		 * wait for the bus to transition to not busy before returning,
		 * the IIC device cannot be disabled until this occurs. It
		 * should transition as the MSMS bit of the control register was
		 * cleared before the last byte was read from the FIFO
		 */
		while (1) {
			if (XIic_ReadIisr(BaseAddress) & XIIC_INTR_BNB_MASK) {
				break;
			}
		}
	}

	return ByteCount;
}
void i2c_write(uint8_t address, uint8_t *data, int len) {
	int SentByteCount = XIic_Send(IIC_BASE_ADDRESS, address >> 1, data, len, XIIC_STOP);

}

ATCA_STATUS i2c_read(uint8_t address, uint8_t *data, uint16_t len, int start, int dostop) {
	int ReceivedByteCount = XIic_Recv(IIC_BASE_ADDRESS, address >> 1, data, len, (dostop) ? XIIC_STOP : XIIC_REPEATED_START);
	return (ReceivedByteCount == len) ? ATCA_SUCCESS : ATCA_COMM_FAIL;
}
/****************************************/

/**
 * \brief
 * This HAL implementation assumes you've included the Plib libraries in your project, otherwise,
 * the HAL layer will not compile because the Plib drivers are a dependency
 */

/** \brief discover i2c buses available for this hardware
 * this maintains a list of logical to physical bus mappings freeing the application
 * of the a-priori knowledge.This function is currently not implemented.
 * \param[in] i2c_buses - an array of logical bus numbers
 * \param[in] max_buses - maximum number of buses the app wants to attempt to discover
 * \return ATCA_UNIMPLEMENTED
 */
ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses) {
	return ATCA_UNIMPLEMENTED;
}

/** \brief discover any CryptoAuth devices on a given logical bus number.This function is currently not implemented.
 * \param[in] bus_num - logical bus number on which to look for CryptoAuth devices
 * \param[out] cfg[] - pointer to head of an array of interface config structures which get filled in by this method
 * \param[out] *found - number of devices found on this bus
 * \return ATCA_UNIMPLEMENTED
 */
ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found) {
	return ATCA_UNIMPLEMENTED;
}

/**
 * \brief
 * hal_i2c_init manages requests to initialize a physical interface. It manages use counts so when an interface
 * has released the physical layer, it will disable the interface for some other use.
 * You can have multiple ATCAIFace instances using the same bus, and you can have multiple ATCAIFace instances on
 * multiple i2c buses, so hal_i2c_init manages these things and ATCAIFace is abstracted from the physical details.
 */

/**
 * \brief initialize an I2C interface using given config
 *
 * \param[in] hal - opaque ptr to HAL data
 * \param[in] cfg - interface configuration
 *
 * \return ATCA_SUCCESS on success, otherwise an error code.
 */
ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg) {
	if (cfg->atcai2c.bus >= MAX_I2C_BUSES) {
		return ATCA_COMM_FAIL;
	}
	ATCAI2CMaster_t* data = &i2c_hal_data[cfg->atcai2c.bus];

	//data->iic = &IicInstance;

	((ATCAHAL_t*) hal)->hal_data = data;

	*((uint32_t*) (IIC_BASE_ADDRESS + 0x13c)) = 600;   //472;
	*((uint32_t*) (IIC_BASE_ADDRESS + 0x140)) = 600;   //472;

	return ATCA_SUCCESS;
}

/**
 * \brief HAL implementation of I2C post init
 *
 * \param[in] iface  instance
 *
 * \return ATCA_SUCCESS
 */
ATCA_STATUS hal_i2c_post_init(ATCAIface iface) {
	return ATCA_SUCCESS;
}

/**
 * \brief HAL implementation of I2C send over ASF
 *
 * \param[in] iface     instance
 * \param[in] txdata    pointer to space to bytes to send
 * \param[in] txlength  number of bytes to send
 *
 * \return ATCA_SUCCESS on success, otherwise an error code.
 */
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t *txdata, int txlength) {
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;

	txdata[0] = 0x03;   // insert the Word Address Value, Command token
	txlength++;         // account for word address value byte.

	i2c_write(cfg->atcai2c.slave_address, txdata, txlength);

	return ATCA_SUCCESS;
}

/**
 * \brief HAL implementation of I2C receive function for ASF I2C
 * \param[in]    iface     Device to interact with.
 * \param[out]   rxdata    Data received will be returned here.
 * \param[inout] rxlength  As input, the size of the rxdata buffer.
 *                         As output, the number of bytes received.
 * \return ATCA_SUCCESS on success, otherwise an error code.
 */
ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength) {
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	int count;
	int retries = 10;
	int status = !ATCA_SUCCESS;
	uint16_t rxdata_max_size = *rxlength;

	*rxlength = 0;

	count = XIic_RecvVar(IIC_BASE_ADDRESS, cfg->atcai2c.slave_address, rxdata, XIIC_STOP, rxdata_max_size);
	if (!count)
		return ATCA_COMM_FAIL;
/*
	if (rxdata_max_size < 1) {
		return ATCA_SMALL_BUFFER;
	}

	while (retries-- > 0 && status != ATCA_SUCCESS) {
		status = i2c_read(cfg->atcai2c.slave_address, rxdata, 1, 1, 0);
	}

	if (status != ATCA_SUCCESS) {
		return ATCA_COMM_FAIL;
	}
	if (rxdata[0] < ATCA_RSP_SIZE_MIN) {
		return ATCA_INVALID_SIZE;
	}
	if (rxdata[0] > rxdata_max_size) {
		return ATCA_SMALL_BUFFER;
	}

	count = rxdata[0] - 1;
	status = i2c_read(cfg->atcai2c.slave_address, &rxdata[1], count, 0, 1);
	if (status != ATCA_SUCCESS) {
		return ATCA_COMM_FAIL;
	}
*/
	*rxlength = rxdata[0];

	return ATCA_SUCCESS;
}

/**
 * \brief method to change the bus speed of I2C
 *
 * \param[in] iface  interface on which to change bus speed
 * \param[in] speed  baud rate (typically 100000 or 400000)
 */
void change_i2c_speed(ATCAIface iface, uint32_t speed) {
	/*	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	 int bus = cfg->atcai2c.bus;

	 // Disable the I2C bus
	 I2CEnable(i2c_hal_data[bus].id, FALSE);

	 // Set the I2C baudrate
	 I2CSetFrequency(i2c_hal_data[bus].id, GetPeripheralClock(), speed);

	 // Enable the I2C bus
	 I2CEnable(i2c_hal_data[bus].id, TRUE);*/
}

/**
 * \brief wake up CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to wakeup
 *
 * \return ATCA_SUCCESS on success, otherwise an error code.
 */
ATCA_STATUS hal_i2c_wake(ATCAIface iface) {
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint32_t bdrt = cfg->atcai2c.baud;

	uint8_t data[4];

	if (bdrt != 100000)     // if not already at 100KHz, change it
			{
		change_i2c_speed(iface, 100000);
	}

	// Send 0x00 as wake pulse
	//uint8_t d=0;
	//i2c_write(i2c_hal_data[bus].iic, 0x00, &d, 1);

	//XIic_WriteReg(i2c_hal_data[bus].iic->BaseAddress, XIIC_DTR_REG_OFFSET, 0);

	*(((uint32_t*)(IIC_BASE_ADDRESS+0x124))) = 0x1;
	atca_delay_us(80);
	//atca_delay_ms(3);   // wait tWHI + tWLO which is configured based on device type and configuration structure
	*(((uint32_t*)(IIC_BASE_ADDRESS+0x124))) = 0x0;
	//atca_delay_us(cfg->wake_delay);

	atca_delay_us(cfg->wake_delay);

	// if necessary, revert baud rate to what came in.
	if (bdrt != 100000) {
		change_i2c_speed(iface, cfg->atcai2c.baud);
	}

	i2c_read(cfg->atcai2c.slave_address, data, 4, 1, 1);

	return hal_check_wake(data, 4);
}

/**
 * \brief idle CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to idle
 *
 * \return ATCA_SUCCESS
 */
ATCA_STATUS hal_i2c_idle(ATCAIface iface) {
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];

	data[0] = 0x02; // idle word address value

	i2c_write(cfg->atcai2c.slave_address, data, 1);

	return ATCA_SUCCESS;
}

/**
 * \brief sleep CryptoAuth device using I2C bus
 *
 * \param[in] iface  interface to logical device to sleep
 *
 * \return ATCA_SUCESS
 */
ATCA_STATUS hal_i2c_sleep(ATCAIface iface) {
	ATCAIfaceCfg *cfg = atgetifacecfg(iface);
	int bus = cfg->atcai2c.bus;
	uint8_t data[4];

	data[0] = 0x01; // idle word address value

	i2c_write(cfg->atcai2c.slave_address, data, 1);

	return ATCA_SUCCESS;
}

/**
 * \brief manages reference count on given bus and releases resource if no more refences exist
 *
 * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation
 *
 * \return ATCA_SUCESS
 */
ATCA_STATUS hal_i2c_release(void *hal_data) {
	ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*) hal_data;

	return ATCA_SUCCESS;
}

/** @} */
